﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RimWorld;
using RimWorld.Planet;
using UnityEngine;
using Verse;
using Verse.AI;
using Verse.Sound;

namespace RimZombieGirl
{
    public class Building_TransformationCoffin : Building_Grave, IThingHolder
    {

        //public Building_TransformationCoffin()
        //{
        //    innerContainer = new ThingOwner<Thing>(this, false, LookMode.Deep);
        //    ingredients = new ThingOwner<Thing>();
        //}

        /*
         * TODO 一些按钮
         */
        public List<Thing> LinkedFacilities
        {
            get
            {
                var compAffectedByFacilities = this.GetComp<CompAffectedByFacilities>();
                if (compAffectedByFacilities == null)
                    return null;
                return compAffectedByFacilities.LinkedFacilitiesListForReading;
            }
        }

        public override IEnumerable<Gizmo> GetGizmos()
        {
            foreach (var gizmo in base.GetGizmos())
            {
                if (gizmo is Command_Action cmd && cmd.action?.Method.Name == "Open")
                    continue;


                yield return gizmo;
            }

            if (CoffinStatus == TransformingStatus.Idle)
            {
                yield return new Gizmo_StartTransform(this);
                yield return new Gizmo_AbortTransform(this);
            }
            else if (CoffinStatus == TransformingStatus.Filling)
            {
                yield return new Gizmo_AbortTransform(this);
            }
            else if(CoffinStatus == TransformingStatus.Transforming)
            {
                yield return new Gizmo_AbortTransform(this);
            }

            if (DebugSettings.godMode &&
                (/*CoffinStatus == TransformingStatus.Filling || */CoffinStatus == TransformingStatus.Transforming))
            {
                yield return new Command_Action
                {
                    defaultLabel = "DEBUG: Finish transforming.",
                    defaultDesc = "Finishes transforming the pawn.",
                    action = () => CoffinStatus = TransformingStatus.Finished
                };
            }
        }



        public Pawn currentPawn
        {
            get
            {
                return this.innerContainer.FirstOrDefault<Thing>() as Pawn;
            }
        }
        

        public override void EjectContents()
        {
            innerContainer.TryDropAll(this.InteractionCell, base.Map, ThingPlaceMode.Near, null, null, true);
            contentsKnown = true;
            //Notify_PawnEntered();
        }

        public override bool CanOpen
        {
            get
            {
                return HasAnyContents;
            }
        }

        public override void Open()
        {
            if (!HasAnyContents)
            {
                return;
            }
            EjectContents();
            tickToTrans = 0;
        }

        public override bool Accepts(Thing thing)
        {
            if (!base.Accepts(thing))
            {
                return false;
            }

            // 活人
            Pawn pawn = thing as Pawn;
            if (pawn != null && pawn.RaceProps.Humanlike && pawn.health.Dead == false)
            {
                // 活人不受 HasCorpse 限制，直接允许
                CoffinStatus = TransformingStatus.Idle;
                return true;
            }

            // 尸体
            Corpse corpse = thing as Corpse;
            if (corpse != null)
            {
                // 棺材里已经有尸体了 -> 拒绝
                if (base.HasCorpse)
                {
                    return false;
                }
                // 棺材里已经有活人了 -> 拒绝
                if (innerContainer!=null)
                {
                    if(this.currentPawn != null)
                    {
                        return false;
                    }
                    
                }
                // 如果有指定 pawn，只能接受对应的尸体
                if (this.AssignedPawn != null && corpse.InnerPawn != this.AssignedPawn)
                {
                    return false;
                }

                // 检查存储设置
                if (!this.storageSettings.AllowedToAccept(thing))
                {
                    return false;
                }

                CoffinStatus = TransformingStatus.Idle;
                return true;
            }

            return false;
        }

        public override bool TryAcceptThing(Thing thing, bool allowSpecialEffects = true)
        {
            //Pawn pawn = thing as Pawn;
            if (thing == null)
            {
                Log.Error(string.Concat(new string[]
                {
                    base.ThingID,
                    " accepted non pawn ",
                    thing.ThingID,
                    "/",
                    thing.GetType().Name,
                    "! this should never happen"
                }));
                return false;
            }
            if (innerContainer.TryAdd(thing, true))
            {
                if (thing.Faction != null && thing.Faction.IsPlayer)
                {
                    contentsKnown = true;
                }
                CoffinStatus = TransformingStatus.Idle;
                Log.Message(CoffinStatus);
                //InitiatePawnTransform();
                return true;
            }
            Log.Warning("Could not add to container");
            return false;
        }

        public override Graphic Graphic
        {
            get
            {
                if (transformProperties.hidePawnGraphic == null)
                {
                    return base.Graphic;
                }
                if ((currentPawn==null)&&(currentCorpse==null))
                {
                    return base.Graphic;
                }
                if (cachedGraphicFull == null)
                {
                    cachedGraphicFull = transformProperties.hidePawnGraphic.GraphicColoredFor(this);
                }
                return cachedGraphicFull;
            }
        }

        /*public void Notify_PawnEntered()
        {
            base.Map.mapDrawer.MapMeshDirty(base.Position, 0);//TODO
        }*/

        public float Fuel
        {
            get
            {
                CompRefuelable comp = this.GetComp<CompRefuelable>();
                return comp.Fuel;
            }
        }


        private void ResetProcess()
        {
            CoffinStatus = TransformingStatus.WaitingForPawn;
        }
        /*
         *TODO 判断Pawn是否为僵尸，转化与升级判定
         */
        public bool IsPawnZombie()
        {
            Pawn pawn = null;

            // 如果当前有尸体，就取尸体里的 pawn
            if (currentCorpse != null)
            {
                pawn = currentCorpse.InnerPawn;
            }
            else if (innerContainer != null) // 否则取当前存储的 pawn（你自己替换成实际字段名）
            {
                pawn =currentPawn;
            }

            if (pawn == null) return false;       // 没有 pawn
            if (pawn.genes == null) return false; // 防止 genes 为空

            return pawn.genes.HasActiveGene(ZombieDefOf.RI_ZombieCore_Aspect_DeadButNotDead);
        }
        public bool CanLevelUp()
        {
            Pawn pawn = null;
            if(currentPawn != null)
            {
                if (pawn.health?.hediffSet?.HasHediff(HediffDefOf.DeathRefusal) ?? false)
                    return true;
                else
                    return false;
            }
                     
            return false;
        }


        public void InitiatePawnTransform()
        {
            int baseTicks = this.transformProperties.ticksToConvert;

            // 遍历所有设施
            var facilities = LinkedFacilities;
            if (facilities != null)
            {
                foreach (var facility in facilities)
                {
                    var coffinFac = facility.TryGetComp<RimZombieGirl.CompFacilityForCoffin>();
                    if (coffinFac != null)
                    {
                        int daysReduce = coffinFac.Props.transformTimeReduce;
                        int ticksReduce = daysReduce * 60000; // 1 天 = 60,000 ticks
                        baseTicks -= ticksReduce;
                    }
                }
            }

            // 防止负数
            baseTicks = Math.Max(60000, baseTicks);

            this.remainingTickTracker = baseTicks;
            this.CoffinStatus = TransformingStatus.Filling;
            //Log.Message($"Transform started, remaining ticks: {remainingTickTracker}");
        }


        public void EjectPawn()
        {
            ingredients.Clear();


            Open();
            ResetProcess();
        }
        /*
         * TODO 根据僵尸Pawnkind写
         */
        public void CompleteConversion()
        {
            void DisableAutoRefuelIfNeeded()
            {
                var comp = this.GetComp<CompRefuelable>();
                if (comp != null && comp.allowAutoRefuel != false)
                    comp.allowAutoRefuel = false;
            }
            XenotypeDef mingXueXenotypeDef = ZombieDefOf.RI_ExorcismXenotype_Necrosapiens;

            // 如果当前是放入的尸体
            if (currentCorpse != null)
            {
                Pawn corpsePawn = currentCorpse.InnerPawn;
                // 尝试复活（如果成功，则对复活后的 pawn 添加基因）
                bool resurrected = ResurrectionUtility.TryResurrect(corpsePawn);
                if (resurrected)
                {
                    // 刷新外观
                    if (corpsePawn.Drawer?.renderer != null)
                        corpsePawn.Drawer.renderer.SetAllGraphicsDirty();
                    corpsePawn.apparel.DropAll(corpsePawn.Position);
                    // 仅添加 冥血类型基因（不做其它转换）
                    if (corpsePawn.genes != null && mingXueXenotypeDef != null)
                    {
                        // 防止重复添加
                        if (!(corpsePawn.genes.Xenotype==ZombieDefOf.RI_ExorcismXenotype_Necrosapiens))
                        {
                            corpsePawn.genes.SetXenotype(mingXueXenotypeDef); 
                            Log.Message($"Changed Xenotype {mingXueXenotypeDef.defName} to resurrected pawn {corpsePawn.Name}");
                        }
                        else
                        {
                            Log.Message($"Pawn {corpsePawn.Name} already {mingXueXenotypeDef.defName}");
                        }
                    }
                    else
                    {
                        Log.Warning($"Cannot add gene: pawn.genes or geneDef is null for {corpsePawn?.Name?.ToStringShort}");
                    }
                }
                else
                {
                    Log.Warning($"TryResurrect failed for {corpsePawn?.Name?.ToStringShort}");
                }

                DisableAutoRefuelIfNeeded();
            }
            else if (currentPawn != null)
            {
                Pawn pawn = currentPawn;

                if (pawn == null)
                {
                    Log.Warning("CompleteConversion called but currentPawn is null.");
                    DisableAutoRefuelIfNeeded();
                    Open();
                    ResetProcess();
                    return;
                }

                if (!IsPawnZombie())
                {
                    pawn.apparel.DropAll(pawn.Position);
                    // 非僵尸：改为冥血类型基因
                    if (pawn.genes != null && mingXueXenotypeDef != null)
                    {
                        if (!(pawn.genes.Xenotype == ZombieDefOf.RI_ExorcismXenotype_Necrosapiens))
                        {
                            pawn.genes.SetXenotype(mingXueXenotypeDef);
                            Log.Message($"changed xenoType {mingXueXenotypeDef.defName} to pawn {pawn.Name}");
                        }
                        else
                        {
                            Log.Message($"Pawn {pawn.Name} already was {mingXueXenotypeDef.defName}");
                        }
                    }
                    else
                    {
                        Log.Warning($"Cannot add gene: pawn.genes or geneDef is null for {pawn?.Name?.ToStringShort}");
                    }

                    if (pawn.Drawer != null && pawn.Drawer.renderer != null)
                    {
                        pawn.Drawer.renderer.SetAllGraphicsDirty();
                    }
                    else
                    {
                        Log.Warning($"[RI_ZombieCoffin] {pawn.LabelShort} 的 Drawer 或 Renderer 为空，无法刷新外观");
                    }


                    DisableAutoRefuelIfNeeded();
                }
                else
                {
                    // 已经是僵尸：调用升级方法
                    DisableAutoRefuelIfNeeded();
                    Log.Message("Calling UpgradeZombie for " + pawn.Name.ToStringShort);
                    //UpgradeZombie(pawn);
                    PawnExts.UpgradeZombieLevel(pawn); //TODO

                    // 对僵尸，清理不良 Hediff（原来逻辑）
                    if (pawn.health?.hediffSet != null)
                    {
                        // 先拷贝到列表再删除，避免在枚举时修改集合导致异常
                        var badHediffs = pawn.health.hediffSet.hediffs.Where(h => h.def.isBad).ToList();
                        foreach (var hd in badHediffs)
                        {
                            pawn.health.RemoveHediff(hd);
                        }
                    }
                    Log.Message("ZombieLevelup: " + pawn.Name.ToStringShort);
                }
            }
            else
            {
                // 既没有尸体也没有活人
                Log.Warning("CompleteConversion: no corpse and no pawn in coffin.");
                DisableAutoRefuelIfNeeded();
            }

            // 完成后打开（弹出物品/尸体）并重置状态
            Open();
            ResetProcess();
        }

        private void UpgradeZombie(Pawn pawn)
        {
            if (pawn == null || pawn.health == null) return;

            var hediffs = pawn.health.hediffSet;

            // 找到当前等级
            Hediff currentLevel = null;
            int currentIndex = -1;

            for (int i = 0; i < RIHediffDefOf.ZombieLevels.Count; i++)
            {
                var def = RIHediffDefOf.ZombieLevels[i];
                var h = hediffs.GetFirstHediffOfDef(def);
                if (h != null)
                {
                    currentLevel = h;
                    currentIndex = i;
                    break;
                }
            }

            if (currentLevel == null)
            {
                pawn.health.AddHediff(RIHediffDefOf.RI_ZombieLevel1);
                return;
            }

            // 已经是最高级
            if (currentIndex >= RIHediffDefOf.ZombieLevels.Count - 1)
            {
                Messages.Message($"{pawn.LabelShort} 已达到最高僵尸等级。", pawn, MessageTypeDefOf.NeutralEvent);
                return;
            }

            // 移除当前等级
            pawn.health.RemoveHediff(currentLevel);

            // 添加下一级
            var nextLevelDef = RIHediffDefOf.ZombieLevels[currentIndex + 1];
            pawn.health.AddHediff(nextLevelDef);

            Hediff hunger = hediffs.GetFirstHediffOfDef(RIHediffDefOf.RI_MeatHunger);
            if (hunger != null)
            {
                pawn.health.RemoveHediff(hunger);
            }

            // 提示信息
            Messages.Message($"{pawn.LabelShort} 升级为 {nextLevelDef.label}！", pawn, MessageTypeDefOf.PositiveEvent);
        }

        public bool CanEnter(Pawn testPawn)
        {
            // 只要是人类活人就允许
            if (testPawn.RaceProps.Humanlike && !testPawn.Dead)
            {
                return true;
            }
            return false;
        }

        public override IEnumerable<FloatMenuOption> GetFloatMenuOptions(Pawn myPawn)
        {
            if (QuestUtility.IsQuestLodger(myPawn))
            {
                var lodgerBlockedOption = new FloatMenuOption(
                    TranslatorFormattedStringExtensions.Translate("ZombieTransform_CannotUseReason", Translator.Translate("ZombieTransform_LodgersNotAllowed")),
                    null,
                    MenuOptionPriority.Default,
                    null, null, 0f, null, null, true, 0
                );
                yield return lodgerBlockedOption;
                yield break;
            }

            foreach (FloatMenuOption inheritedOption in base.GetFloatMenuOptions(myPawn))
            {
                yield return inheritedOption;
            }

            if (innerContainer.Count == 0)
            {
                if (!ReachabilityUtility.CanReach(myPawn, this, PathEndMode.InteractionCell, Danger.Deadly, false, false, 0))
                {
                    var noPathOption = new FloatMenuOption(
                        Translator.Translate("ZombieTransform_CannotReach"),
                        null,
                        MenuOptionPriority.Default,
                        null, null, 0f, null, null, true, 0
                    );
                    yield return noPathOption;
                }
                else if (!CanEnter(myPawn))
                {
                    var cannotConvertOption = new FloatMenuOption(
                        Translator.Translate("ZombieTransform_CannotConvert"),
                        null,
                        MenuOptionPriority.Default,
                        null, null, 0f, null, null, true, 0
                    );
                    yield return cannotConvertOption;
                }
                else
                {
                    JobDef enterCoffinJob = ZGJobDefOf.EnterTransformationCoffin;
                    string label = Translator.Translate("ZombieTransform_EnterCoffin");

                    Action assignJobAction = delegate ()
                    {
                        Job job = JobMaker.MakeJob(enterCoffinJob, this);
                        myPawn.jobs.TryTakeOrderedJob(job, new JobTag?(0), false);
                    };

                    var enterCoffinOption = new FloatMenuOption(
                        label,
                        assignJobAction,
                        MenuOptionPriority.Default,
                        null, null, 0f, null, null, true, 0
                    );

                    yield return FloatMenuUtility.DecoratePrioritizedTask(
                        enterCoffinOption, myPawn, this, "ReservedBy"
                    );
                }
            }
            yield break;
        }


        public override void SpawnSetup(Map map, bool respawningAfterLoad)
        {
            base.SpawnSetup(map, respawningAfterLoad);

            transformProperties = this.def.GetModExtension<PawnTransformProperites>();
            /*if (!respawningAfterLoad)
            {
                if (transformProperties == null)
                {
                    transformProperties = new PawnTransformProperites();
                }
            }*/
        }

        public override void PostMake()
        {
            base.PostMake();
        }

        public override void ExposeData()
        {
            base.ExposeData();
            Scribe_Deep.Look<ThingOwner<Thing>>(ref ingredients, "ingredients", Array.Empty<object>());
            Scribe_Values.Look<TransformingStatus>(ref CoffinStatus, "coffinStatus", TransformingStatus.Idle, false);
            Scribe_Values.Look<int>(ref remainingTickTracker, "transformingTicksLeft", 0, false);
            Scribe_Values.Look<int>(ref nextResourceTick, "nextResourceTick", 0, false);
            Scribe_Deep.Look<StorageSettings>(ref inputSettings, "inputSettings", Array.Empty<object>());
            /*Scribe_Deep.Look<ThingOrderProcessor>(ref orderProcessor, "orderProcessor", new object[]
            {
                ingredients,
                inputSettings
            });*/
            Scribe_Values.Look<int>(ref tickToTrans, "totaltimeCost", 0, false);
            Scribe_Deep.Look<ThingOwner>(ref innerContainer, "innerContainer", new object[]
            {
                this
            });
            Scribe_Values.Look<bool>(ref contentsKnown, "contentsKnown", false, false);

        }

        public override void Destroy(DestroyMode mode = 0)
        {
            if (mode > 0)
            {
                ingredients.Clear();
            }
            base.Destroy(mode);
        }

        /*
         * TODO 信息卡
         */
        public override string GetInspectString()
        {
            // 如果该建筑不在地图上，则保持默认行为
            if (base.ParentHolder != null && !(base.ParentHolder is Map))
            {
                return base.GetInspectString();
            }

            StringBuilder sb = new StringBuilder();

            // 当前状态
            string statusKey = "ZombieTransformingStatus";                  // 主标签
            string enumKey = "ZombieTransformingStatusEnum";               // 枚举翻译前缀
            int statusIndex = (int)CoffinStatus;

            // 拼接状态
            sb.AppendLine(TranslatorFormattedStringExtensions.Translate(
                statusKey,
                Translator.Translate(enumKey + statusIndex.ToString())
            ));

            // 如果正在转化，显示剩余时间
            if (CoffinStatus == TransformingStatus.Transforming)
            {
                sb.AppendLine(
                    TranslatorFormattedStringExtensions.Translate(
                        "ZombieTransformingRemainingTime",
                        remainingTickTracker.ToStringTicksToPeriod() // 转化为 RimWorld 时间格式
                    )
                );
            }

            // 如果只要状态 + 剩余时间，这里不加任何材料等信息

            return GenText.TrimEndNewlines(sb.ToString());
        }


        protected override void Tick()
        {
            base.Tick();

            if (soundSustainer != null && !soundSustainer.Ended)
            {
                soundSustainer.End();
            }
            CompRefuelable comp = this.GetComp<CompRefuelable>();
            if (comp.allowAutoRefuel != false)
            {
                comp.allowAutoRefuel = false;//TODO 重置的时候改成false
            }
            switch (CoffinStatus)
                {
                    case TransformingStatus.Filling:
                        handleFillingTick();
                        return;
                    case TransformingStatus.Transforming:
                        handleTransformingTick();
                        return;
                    case TransformingStatus.Finished:
                        handleFinalTick();
                        return;
                    default:
                        if (soundSustainer != null && !soundSustainer.Ended)
                        {
                            soundSustainer.End();
                        }
                        break;
                }
            
        }
        /*
         * TODO 三状态
         */
        public void handleFillingTick()
        {
            CompRefuelable comp = this.GetComp<CompRefuelable>();
            if(comp.allowAutoRefuel != true)
            {
                comp.allowAutoRefuel = true;//TODO 重置的时候改成false
            }

            if (comp.Fuel>=transformProperties.costCount && (currentCorpse!=null||HasAnyContents))
            {
                CoffinStatus = TransformingStatus.Transforming;
                Log.Message(CoffinStatus);
            }
        }

        public void handleTransformingTick()
        {
            CompRefuelable comp = this.GetComp<CompRefuelable>();
            if (comp.allowAutoRefuel != true)
            {
                comp.allowAutoRefuel = true;//TODO 重置的时候改成false
            }
            if (Current.Game.tickManager.TicksGame % 100 == 0)
            {
                //FleckMaker.ThrowSmoke(base.Position.ToVector3(), base.Map, 1.33f);
            }
            if (Current.Game.tickManager.TicksGame % 250 == 0)
            {
                for (int i = 0; i < 3; i++)
                {
                    FleckMaker.ThrowMicroSparks(base.Position.ToVector3() + new Vector3((float)Rand.Range(-1, 1), 0f, (float)Rand.Range(-1, 1)), base.Map);
                }
            }
            if (Current.Game.tickManager.TicksGame % 60000 == 0)
            {
                float cost = 3;
                var facilities = LinkedFacilities;
                if (facilities != null)
                {
                    foreach (var facility in facilities)
                    {
                        var coffinFac = facility.TryGetComp<RimZombieGirl.CompFacilityForCoffin>();
                        if (coffinFac != null)
                        {
                            cost *= 1f - coffinFac.Props.dailyConsumptionReduction;
                        }
                    }
                }

                comp.ConsumeFuel(cost);
            }

            if (soundSustainer == null || soundSustainer.Ended)
            {
                SoundDef craftingSound = transformProperties.craftingSound;
                if (craftingSound != null && craftingSound.sustain)
                {
                    SoundInfo soundInfo = SoundInfo.InMap(this, MaintenanceType.PerTick);
                    soundSustainer = SoundStarter.TrySpawnSustainer(craftingSound, soundInfo);
                }
            }
            if (soundSustainer != null && !soundSustainer.Ended)
            {
                soundSustainer.Maintain();
            }


            if (remainingTickTracker > 0)
            {
                remainingTickTracker--;
                return;
            }
            CoffinStatus = TransformingStatus.Finished;



        }

        public void handleFinalTick()
        {
            ingredients.ClearAndDestroyContents(0);
            FilthMaker.TryMakeFilth(this.InteractionCell, base.Map, RimWorld.ThingDefOf.Filth_Slime, 5, 0);
            ChoiceLetter choiceLetter;

            if (currentCorpse != null)
            {
                // 尸体转化
                var pawn = currentCorpse.InnerPawn;
                string shortName = pawn?.Name?.ToString() ?? "Unknown";
                string fullName = pawn?.Name?.ToString() ?? "Unknown";

                choiceLetter = LetterMaker.MakeLetter(
                    TranslatorFormattedStringExtensions.Translate("ZombieTransformLetterLabel", shortName),
                    TranslatorFormattedStringExtensions.Translate("ZombieTransformLetterDescription", fullName),
                    LetterDefOf.PositiveEvent,
                    currentCorpse,
                    null,
                    null,
                    null
                );
            }
            else if (currentPawn != null)
            {
                if (IsPawnZombie())
                {
                    // 活人转化-升级
                    var pawn = currentPawn;
                    string shortName = pawn?.Name?.ToString() ?? "Unknown";
                    string fullName = pawn?.Name?.ToString() ?? "Unknown";

                    choiceLetter = LetterMaker.MakeLetter(
                        TranslatorFormattedStringExtensions.Translate("ZombieLevelUpLetterLabel", shortName),
                        TranslatorFormattedStringExtensions.Translate("ZombieLevelUpLetterDescription", fullName),
                        LetterDefOf.PositiveEvent,
                        currentPawn,
                        null,
                        null,
                        null
                    );
                }
                else
                {
                    // 活人转化
                    var pawn = currentPawn;
                    string shortName = pawn?.Name?.ToString() ?? "Unknown";
                    string fullName = pawn?.Name?.ToString() ?? "Unknown";

                    choiceLetter = LetterMaker.MakeLetter(
                        TranslatorFormattedStringExtensions.Translate("ZombieTransformLetterLabel", shortName),
                        TranslatorFormattedStringExtensions.Translate("ZombieTransformLetterDescription", fullName),
                        LetterDefOf.PositiveEvent,
                        currentPawn,
                        null,
                        null,
                        null
                    );
                }

            }
            else
            {
                // 都不存在时
                Log.Warning("[RI_ZombieCoffin] handleFinalTick: 没有尸体也没有活人，无法生成 Letter");
                return;
            }

            Find.LetterStack.ReceiveLetter(choiceLetter, null);

            CompRefuelable comp = this.GetComp<CompRefuelable>();
            if (comp.allowAutoRefuel != false)
            {
                comp.allowAutoRefuel = false;
            }
            CompleteConversion();
        }
        /*
         * TODO 计算冥血需求量，目前为营养值，待修改
         */
        //public float CountNutrition()
        //{
        //    float num = 0f;
        //    foreach (Thing thing in ingredients)
        //    {
        //        Corpse corpse = thing as Corpse;
        //        if (corpse != null)
        //        {
        //            if (!RottableUtility.IsDessicated(corpse))
        //            {
        //                num += FoodUtility.GetBodyPartNutrition(corpse, corpse.InnerPawn.RaceProps.body.corePart);
        //            }
        //        }
        //        else if (thing.def.IsIngestible)
        //        {
        //            ThingDef def = thing.def;
        //            num += (def != null ? def.ingestible.CachedNutrition : 1f) * (float)thing.stackCount;
        //        }
        //    }
        //    return num;
        //}

        //public string FormatIngredientCosts(out bool needsFulfilled, IEnumerable<ThingOrderRequest> requestedItems, bool deductCosts = true)
        //{
        //    StringBuilder stringBuilder = new StringBuilder();
        //    needsFulfilled = true;
        //    foreach (ThingOrderRequest thingOrderRequest in requestedItems)
        //    {
        //        if (thingOrderRequest.nutrition)
        //        {
        //            float num = CountNutrition();
        //            if (deductCosts)
        //            {
        //                float num2 = thingOrderRequest.amount - num;
        //                if (num2 > 0f)
        //                {
        //                    stringBuilder.Append(TranslatorFormattedStringExtensions.Translate("ZombiePrinterNeed", num2, Translator.Translate("ZombieNutrition")) + " ");
        //                    needsFulfilled = false;
        //                }
        //            }
        //            else
        //            {
        //                stringBuilder.Append(TranslatorFormattedStringExtensions.Translate("ZombiePrinterNeed", thingOrderRequest.amount, Translator.Translate("ZombieNutrition")) + " ");
        //            }
        //        }
        //        else
        //        {
        //            int num3 = ingredients.TotalStackCountOfDef(thingOrderRequest.thingDef);
        //            if (deductCosts)
        //            {
        //                if ((float)num3 < thingOrderRequest.amount)
        //                {
        //                    stringBuilder.Append(TranslatorFormattedStringExtensions.Translate("ZombiePrinterNeed", thingOrderRequest.amount - (float)num3, thingOrderRequest.thingDef.LabelCap) + " ");
        //                    needsFulfilled = false;
        //                }
        //            }
        //            else
        //            {
        //                stringBuilder.Append(TranslatorFormattedStringExtensions.Translate("ZombiePrinterNeed", thingOrderRequest.amount, thingOrderRequest.thingDef.LabelCap) + " ");
        //            }
        //        }
        //    }
        //    return stringBuilder.ToString();
        //}

        public Corpse currentCorpse
        {
            get
            {
                return innerContainer
                    .OfType<Corpse>()
                    .FirstOrDefault();
            }
        }



        protected bool contentsKnown;


        public ThingOwner<Thing> ingredients = new ThingOwner<Thing>();


        public TransformingStatus CoffinStatus;


        //protected ThingOwner innerContainer;


        public int nextResourceTick;


        public int tickToTrans;


        public int remainingTickTracker;


        private Sustainer soundSustainer;


        public StorageSettings inputSettings;


        public PawnTransformProperites transformProperties;


        private Graphic cachedGraphicFull;

        public Pawn newPawn;
    }
}
